package com.ruoyi.boat.utils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LocationUtil {

    public static double[] calculateOffsetLatLng(double latA, double lngA, double distance, double heading) {
        double R = 6371e3; // 地球的平均半径，单位为米
        double radLatA = Math.toRadians(latA);
        double radLngA = Math.toRadians(lngA);
        double radBearing = Math.toRadians(heading);

        // 计算偏移纬度
        double latB = Math.asin(Math.sin(radLatA) * Math.cos(distance / R) + Math.cos(radLatA) * Math.sin(distance / R) * Math.cos(radBearing));
        double offsetLat = Math.toDegrees(latB - radLatA);

        // 计算偏移经度
        double lngB = radLngA + Math.atan2(Math.sin(radBearing) * Math.sin(distance / R) * Math.cos(radLatA),
                Math.cos(distance / R) - Math.sin(radLatA) * Math.sin(latB));
        double offsetLng = Math.toDegrees(lngB - radLngA);

        offsetLng = Double.parseDouble(String.format("%.10f", offsetLng));
        offsetLat = Double.parseDouble(String.format("%.10f", offsetLat));

        return new double[]{offsetLat, offsetLng};
    }

    public static double getHeading(double heading, double angle) {
        double h = heading + angle;
        while (h >= 360.0) {
            h -= 360.0;
        }
        return h;
    }

    /**
     * 得到两点间的距离 米
     *
     * @param lat1
     * @param lng1
     * @param lat2
     * @param lng2
     * @return
     */
    public static double getDistanceOfMeter(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = (double) Math.round(s * 10000) / 10;
        return s;
    }

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 地球半径：6378.137KM
     */
    public static double EARTH_RADIUS = 6378.137;

    public static double METERS_OF_ONE_NM = 1852.0;


    /**
     * 将度转换为度分秒格式
     *
     * @param deg 度数
     * @return 度分秒形式的字符串
     */
    public static String d2dms(double deg) {
        int deg1 = (int) deg;
        //临时变量，将小数部分*60，转化成“分”
        double temp = (deg - deg1) * 60;
        //取“分”的整数部分
        int min = (int) temp;
        //“分”的小数部分*60，保留两位作为“秒”
        String sec = String.format("%02.0f", Math.abs(((temp - min) * 60)));
        //返回完整拼接字符串
        return deg1 + "°" + Math.abs(min) + "'" + sec + "\"";
    }

    /**
     * 将度分秒转换为度
     *
     * @param dms 度分秒
     * @return 度数，double类型
     */
    public static double dms2d(String dms) {
        if (dms == null) return 0;
        try {
            //所有空格替换为""
            dms = dms.replace(" ", "");
            dms = dms.replace("秒", "");
            dms = dms.replace("’", "'");
            dms = dms.replace("分", "'");
            dms = dms.replace("度", "°");
            //按“°”符号分割字符串
            String[] str = dms.split("°");
            if (str.length < 2) return 0;
            //第一部分为“度”
            int d = Integer.parseInt(str[0]);
            String[] str1 = str[1].split("'");
            if (str1.length < 2) return 0;
            int m = Integer.parseInt(str1[0]);
            //这里不应包含最后的“/"”(秒的单位符号)
            String str2 = str1[1].substring(0, str1[1].length() - 1);
            double s = Double.parseDouble(str2);
            double min = m + (s / 60);
            double deg = (min / 60) + Math.abs(d);
            if (d < 0) deg = -deg;
            //返回结果
            return Double.parseDouble(String.format("%.7f", deg));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 将度分转换为度
     *
     * @param d 度
     * @param m 分
     * @return 度数，double类型
     */
    public static double dm2d(int d, double m) {
        try {
            double deg = (m / 60) + Math.abs(d);
            if (d < 0) deg = -deg;
            //返回结果
            return Double.parseDouble(String.format("%.7f", deg));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static double calculateDeviation(double lon_a,double lat_a,double lon_b,double lat_b,double lon_c,double lat_c){
        double k_ab = (lat_b - lat_a) / (lon_b - lon_a); // 斜率
        double k_ac = (lat_c - lat_a) / (lon_c - lon_a);

        double verticalSlope_ab = -1 / k_ab; // 垂直斜率
        double verticalSlope_ac = -1 / k_ac;

        double y_intercept_ab = lat_a - verticalSlope_ab * lon_a; // 截距
        double y_intercept_ac = lat_a - verticalSlope_ac * lon_a;

        // 计算垂直线的交点坐标
        double intersection_lon = (y_intercept_ac - y_intercept_ab) / (verticalSlope_ab - verticalSlope_ac);
        double intersection_lat = verticalSlope_ab * intersection_lon + y_intercept_ab;

        // 计算两点之间的欧几里德距离，作为垂直距离
        return Math.sqrt(Math.pow(intersection_lat - lat_a, 2) + Math.pow(intersection_lon - lon_a, 2));
    }

}
